/**
 * Raft node implementation
 */

#include <xdevice/raft.h>
#include <stdlib.h>
#include <time.h>

/* 节点状态结构 */
typedef struct {
    int node_id;
    xdevice_node_state_t state;
    uint64_t current_term;
    int voted_for;
    uint64_t last_heartbeat;
    pthread_mutex_t lock;
    bool initialized;
} raft_node_t;

static raft_node_t g_node = {0};

int raft_node_init(int node_id) {
    if (g_node.initialized) {
        return 0;
    }
    
    if (pthread_mutex_init(&g_node.lock, NULL) != 0) {
        return -1;
    }
    
    g_node.node_id = node_id;
    g_node.state = XDEVICE_NODE_FOLLOWER;
    g_node.current_term = 0;
    g_node.voted_for = -1;
    g_node.last_heartbeat = time(NULL);
    g_node.initialized = true;
    
    return 0;
}

void raft_node_cleanup(void) {
    if (!g_node.initialized) {
        return;
    }
    
    pthread_mutex_lock(&g_node.lock);
    g_node.initialized = false;
    pthread_mutex_unlock(&g_node.lock);
    
    pthread_mutex_destroy(&g_node.lock);
}

int raft_node_start_election(void) {
    if (!g_node.initialized) {
        return -1;
    }
    
    pthread_mutex_lock(&g_node.lock);
    
    // 成为候选者
    g_node.state = XDEVICE_NODE_CANDIDATE;
    g_node.current_term++;
    g_node.voted_for = g_node.node_id;
    
    pthread_mutex_unlock(&g_node.lock);
    
    // 在真实实现中，这里会向其他节点发送投票请求
    // 现在简化为直接成为leader（单节点情况）
    return raft_node_become_leader();
}

int raft_node_become_leader(void) {
    if (!g_node.initialized) {
        return -1;
    }
    
    pthread_mutex_lock(&g_node.lock);
    g_node.state = XDEVICE_NODE_LEADER;
    pthread_mutex_unlock(&g_node.lock);
    
    // 设置集群中的leader
    raft_cluster_set_leader(g_node.node_id);
    
    return 0;
}

int raft_node_become_follower(void) {
    if (!g_node.initialized) {
        return -1;
    }
    
    pthread_mutex_lock(&g_node.lock);
    g_node.state = XDEVICE_NODE_FOLLOWER;
    g_node.voted_for = -1;
    pthread_mutex_unlock(&g_node.lock);
    
    return 0;
}

xdevice_node_state_t raft_node_get_state(void) {
    if (!g_node.initialized) {
        return XDEVICE_NODE_UNKNOWN;
    }
    
    pthread_mutex_lock(&g_node.lock);
    xdevice_node_state_t state = g_node.state;
    pthread_mutex_unlock(&g_node.lock);
    
    return state;
}

uint64_t raft_node_get_term(void) {
    if (!g_node.initialized) {
        return 0;
    }
    
    pthread_mutex_lock(&g_node.lock);
    uint64_t term = g_node.current_term;
    pthread_mutex_unlock(&g_node.lock);
    
    return term;
}
